/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.tools;

import java.awt.event.ActionEvent;
import java.util.Set;

import javax.swing.SpinnerNumberModel;

import dgbgui.DGBGUI;
import dgbgui.command.AddQueryCommand;
import dgbgui.command.CommandStack;
import dgbgui.command.ReplaceQueryCommand;
import dgbgui.gui.dialogs.NeighbourhoodDialog;
import dgbgui.modeldocument.Query;
import dgbgui.modeldocument.definition.NeighbourhoodDefinition;
import dgbgui.modeldocument.uimodels.QueryComboModel;
import dgbgui.modeldocument.uimodels.RelationTypesComboBoxModel;
import dgbgui.selection.SelectionManager;

public class NeighbourhoodTool extends DialogedTool {

    // TODO: refactor
    public static enum ToolType { CREATE, EDIT };
    
    public NeighbourhoodTool(ToolType type) {
        m_type = type;
    }
    

    public void execute() {
        
        assert (SelectionManager.getInstance().size() == 1);
        Set<Object> selection = SelectionManager.getInstance().getSelection(Query.class);
        assert(selection.size() == 1);
        
        // ----- Creating a closure -----
            
        // ----- From -----

        if ( m_type == ToolType.CREATE ) {
            // From
            Query originalFromQuery = (Query)selection.iterator().next();
            m_fromModel = new QueryComboModel(originalFromQuery);
            
            // Default closure type model
            m_depthModel = new SpinnerNumberModel(2,1,Integer.MAX_VALUE,1);
            
            // Default layer model
            m_layerModel = new QueryComboModel();
            
            // Default Relation Type model
            m_relationModel = new RelationTypesComboBoxModel(RelationTypesComboBoxModel.Type.WITHOUT_ALL_QUERIES);
        }
        
        // ----- Editing a closure -----
        
        if ( m_type == ToolType.EDIT ) {
            m_queryToEdit = (Query)selection.iterator().next(); 
            assert (m_queryToEdit.getDefinition() instanceof NeighbourhoodDefinition);
            NeighbourhoodDefinition currentDefinition = (NeighbourhoodDefinition)m_queryToEdit.getDefinition();

            // From
            Query originalFromQuery = currentDefinition.getFromQuery();
            m_fromModel = new QueryComboModel(originalFromQuery);
            // Avoid recursive definitions
            m_fromModel.removeQuery(m_queryToEdit);
            
            // Closure type model from type
            m_depthModel = new SpinnerNumberModel(2,1,Integer.MAX_VALUE,1);
            m_depthModel.setValue(currentDefinition.getDepth());
            
            // Layer 
            m_layerModel = new QueryComboModel(currentDefinition.getLayerQuery());
            // Avoid recursive definitions
            m_layerModel.removeQuery(m_queryToEdit);
            
            // Relation(s)
            m_relationModel = new RelationTypesComboBoxModel(currentDefinition.getRelationQuery(),RelationTypesComboBoxModel.Type.WITHOUT_ALL_QUERIES);
            // Avoid recursive definitions
            m_relationModel.removeQuery(m_queryToEdit);
        }
        
        // Set the model to use in the dialog
        m_dialog = new NeighbourhoodDialog(this);
        ((NeighbourhoodDialog)m_dialog).setFromModel(m_fromModel);
        ((NeighbourhoodDialog)m_dialog).setDepthModel(m_depthModel);
        ((NeighbourhoodDialog)m_dialog).setLayerModel(m_layerModel);
        ((NeighbourhoodDialog)m_dialog).setRelationModel(m_relationModel);

        m_dialog.pack();
        DGBGUI.centerDialog(m_dialog);
        m_dialog.setVisible(true);
        
        
    }
    
    public void actionPerformed(ActionEvent event) {
        if ( event.getSource() == m_dialog.getOkButton() ) {

            Query fromQuery = ((QueryComboModel)m_fromModel).getSelected();
            int depth = m_depthModel.getNumber().intValue();
            Query layerQuery = ((QueryComboModel)m_layerModel).getSelected();
            Query relationQuery = ((RelationTypesComboBoxModel)m_relationModel).getSelected();

            NeighbourhoodDefinition newDef = new NeighbourhoodDefinition(depth,fromQuery,layerQuery,relationQuery);

            Query newQuery = new Query(newDef);

            if ( m_type == ToolType.CREATE ) {
                CommandStack.getInstance().execute(new AddQueryCommand(newQuery));
            } else {
                CommandStack.getInstance().execute(new ReplaceQueryCommand(m_queryToEdit,newQuery));
            }
        }

        // Close the tool
        doClose();

    }
    
    Query m_queryToEdit;
    QueryComboModel m_layerModel;
    RelationTypesComboBoxModel m_relationModel;
    QueryComboModel m_fromModel;
    SpinnerNumberModel m_depthModel;
    private ToolType m_type;

}
